package com.algorithms.techniques;

import java.util.Arrays;

public class EditDistance {
	int cx = 0;
	int cy = 0;
	char[] z = null;
	char[] x = null;
	char[] y = null;
	int m, n;

	public EditDistance(char[] ix, char[] iy) {
		z = new char[iy.length];
		x = Arrays.copyOf(ix, ix.length);
		y = Arrays.copyOf(iy, iy.length);
		m = x.length;
		n = y.length;
	}

	public void editDistance() {
		while (!kill()) {
			if (twiddle() && !checkNextTwo()) {
				untwiddle();
				if (delete() && insert(y[cy]) && checkNextOne())
				{
					uninsert();
					undelete();
					replace(y[cy]);
					continue;
				}
				if (delete() && !checkNextOne()) {
					undelete();
					if (insert(y[cy]) && !checkNextOne()) {
						uninsert();
						if (copy() && !checkNextOne()) {
							uncopy();
							if (replace(y[cy]) && !checkNextOne()) {
								unreplace();
							} else {
								continue;
							}
						} else {
							continue;
						}
					} else {
						continue;
					}
				} else {
					continue;
				}
			} else 
			{
				continue;
			}

			
			
			
			
		}
	}

	public boolean checkNextOne() {
		if (z[cy] == y[cy])
			return true;
		return false;
	}

	public boolean checkNextTwo() {
		if (z[cy] == y[cy] && z[cy + 1] == y[cy + 1])
			return true;
		return false;
	}

	public boolean copy() {
		if ((cy) == n || (cx) == m)
			return false;
		z[cy] = x[cx];
		cy++;
		cx++;
		System.out.println("COPY");
		return true;
	}

	public void uncopy() {
		cy--;
		cx--;
		System.out.println("UN-COPY");
	}

	public boolean replace(char replace) {
		if ((cy) == n)
			return false;
		z[cy] = replace;
		cy++;
		cx++;
		System.out.println("REPLACE =" + replace);
		return true;
	}

	public void unreplace() {
		cy--;
		cx--;
		System.out.println("UN-REPLACE ");
	}

	public boolean delete() {
		cx++;
		System.out.println("DELETE");
		return true;
	}

	public void undelete() {
		cx--;
		System.out.println("UNDELETE");
	}

	public boolean insert(char insert) {
		if ((cy) == n)
			return false;
		z[cy] = insert;
		cy++;
		System.out.println("INSERT=" + insert);
		return true;
	}

	public void uninsert() {
		System.out.println("UNINSERT");
		cy--;
	}

	public boolean twiddle() {
		if ((cy) == n || (cx) == m)
			return false;
		if ((cy + 1) == n || (cx + 1) == m)
			return false;
		z[cy] = x[cx + 1];
		z[cy + 1] = x[cx];
		cy = cy + 2;
		cx = cx + 2;
		System.out.println("TWIDDLE");
		return true;
	}

	public void untwiddle() {
		cy = cy - 2;
		cx = cx - 2;
		System.out.println("UNTWIDDLE");
	}

	public boolean kill() {
		if (cy == n) {
			cx = m;
			return true;
		}
		return false;
	}
}
